#include "Thread.hpp"
#include "LockGuard.hpp"
#include <string>

void func(string threadname)
{
    while (true)
    {
        cout << "I am a new thread, my thread id is: " << pthread_self() << ", my threadname is " << threadname << endl;
        sleep(1);
    }
}
int tickets = 10000;

string GetThreadName()
{
    static int number = 1;
    char name[64];
    snprintf(name, sizeof(name), "thread-%d", number++);
    return name;
}
// 定义一个全局的锁
// pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER; // 申请锁本身是原子的，所以它是线程安全的
void GetTicket(pthread_mutex_t *lock, const string &threadname)
{
    while (true)
    {
        { // 临界区
            // 加锁
            // pthread_mutex_lock(lock);
            LockGuard lockguard(lock);
            if (tickets > 0)
            {
                usleep(1000);
                // cout << threadname << "get a ticket: " << tickets << endl;
                printf("%s get a ticket: %d\n", threadname.c_str(), tickets);
                tickets--;
                // 去锁
                // pthread_mutex_unlock(lock);
            }
            else
            {
                // pthread_mutex_unlock(lock);
                break;
            }
        }
    }
}

// 让多线程模拟抢票逻辑，验证多线程并发访问时的数据不一致问题
int main()
{
    // 定义一个局部的锁，并肩同一把锁传给线程
    pthread_mutex_t mutex;
    pthread_mutex_init(&mutex, nullptr); // 堆锁进行初始化
    string name1 = GetThreadName();
    thread<pthread_mutex_t *, string> t1(name1, GetTicket, &mutex);
    string name2 = GetThreadName();
    thread<pthread_mutex_t *, string> t2(name2, GetTicket, &mutex);
    string name3 = GetThreadName();
    thread<pthread_mutex_t *, string> t3(name3, GetTicket, &mutex);
    string name4 = GetThreadName();
    thread<pthread_mutex_t *, string> t4(name4, GetTicket, &mutex);
    string name5 = GetThreadName();
    thread<pthread_mutex_t *, string> t5(name5, GetTicket, &mutex);

    t1.Start();
    t2.Start();
    t3.Start();
    t4.Start();
    t5.Start();

    t1.Join();
    t2.Join();
    t3.Join();
    t4.Join();
    t5.Join();

    // 销毁锁
    pthread_mutex_destroy(&mutex);

    return 0;
}

// int main() {
//     // 创建一个线程
//     string threadname = "thread-1";
//     thread<string> t(func, threadname);
//     t.Start();

//     while (true) {
//         cout << "I am main thread, my thread id is: " << pthread_self() << endl;
//         sleep(1);
//     }

//     return 0;
// }